<?php
/*
 * @Author: LDY dong2406@126.com
 * @Date: 2022-09-14 10:32:58
 * @LastEditors: 搬铁的码农 dong2406@126.com
 * @LastEditTime: 2024-06-08 08:56:49
 */

namespace Ldy\Models;

use Ldy\Model;
use Ldy\Models\SysRoleMenu;
use tauthz\facade\Enforcer as Permission;
use Ldy\Models\SysMenuApi;
use Ldy\Models\SysApi;

class SysRole extends Model{
    
    public function getDeptIdsAttr($val){
        $res = [];
        if(!empty($val)) $res = explode(',', $val);
        return $res;
    }

    public function setDeptIdsAttr($val){
        $res = '';
        if(is_array($val)) $res = implode(',', $val);
        return $res;
    }

    public function getMenuAttr($val){
        if(is_array($val)) return $val;
		return empty($val) ? []:explode(',', $val);
    }
    /**
     * 新增后处理
     *
     * @param [type] $model
     * @return void
     */
    public static function onAfterInsert($model){
        $menu = request()->param('menu');
		$id = $model->id;

        if(empty($id)) return false;

        //删除角色的所有权限规则,后面重新执行添加
        $roule_name = casbin_role_field_prefix($id);
		Permission::deletePermissionsForUser($roule_name);

		if(empty($menu)) return false;

		$sysmenuapi = new SysRoleMenu();
		$data = [];
		foreach($menu as $val) $data[] = ['role_id' => $id, 'menu_id'=>$val];
		$sysmenuapi->saveAll($data);

        self::addAuthRule($menu, $id);
        
    }
    /**
     * 更新后处理
     *
     * @return void
     */
    public static function onAfterUpdate($model){
		$menu = request()->param('menu');
        $id = $model->id;

		if(empty($id)) return false;

        //删除角色和菜单的关联关系
        $sysmenuapi = new SysRoleMenu();
        $sysmenuapi->where('role_id', $id)->delete();

        //删除角色的所有权限规则,后面重新执行添加
        $roule_name = casbin_role_field_prefix($id);
		Permission::deletePermissionsForUser($roule_name);
		
        if(empty($menu)) return false;
		$data = [];
		foreach($menu as $val) $data[] = ['role_id' => $id, 'menu_id'=>$val];
		$sysmenuapi->saveAll($data);

        self::addAuthRule($menu, $id);
	}

    /**
     * 获取多个角色数据权限
     *
     * @param Array $roles
     * @return void
     */
    public static function getRoleDataAuth(Array $roles, $isAll = false, Int $dep_id = 0){
        $model = self::where('id', 'in', $roles);
        if(!$isAll) $model = $model->where('status', 1);
        $data = $model->select();

        if(!$dep_id) $dep_id = session('admin.department_id');

        $res = [];

        if($data->isEmpty()) return $res;

        foreach($data as $item){
            $authType = $item->data_auth;
            $val = [];
            
            if($authType == 4){
                $val = $item->dept_ids;
                if(!empty($res[$authType])) $val = array_merge($res[$authType], $val);
            }

            $res[$authType] = $val;
        }

        $depIds = [];
        //所在部门可见
        if(isset($res[2])) $depIds[] = $dep_id;
        //所在部门及子级可见
        if(isset($res[3])) $depIds = array_merge($depIds, SysDepartment::getSonDepIds($dep_id, false));
        //选择的部门可见
        if(isset($res[4])) $depIds = array_merge($depIds, $res[4]);
        //本人可见
        if(!isset($res[2]) && !isset($res[3]) && !isset($res[4]) && isset($res[1])) $depIds = 'admin_id';
        //全部可见
        if(isset($res[0])) $depIds = [];

        return $depIds;

    }
    /**
     * 自定义连表查询
     *
     * @return Model
     */
    // public function setModel(){
	// 	$model = $this->alias('r')
    //     ->field('r.*,GROUP_CONCAT(m.menu_id) AS menu')
    //     ->leftJoin('sys_role_menu m','m.role_id=r.id')
    //     ->group('r.id');

	// 	return $model;
	// }

    /**
     * 增加权限规则
     *
     * @param Array $menu
     * @param Int   $id 角色ID
     * @return void
     */
    private static function addAuthRule(Array $menu, Int $id){
        $menuApi = SysMenuApi::where('menu_id','in', $menu)->select();

        if($menuApi->isEmpty()) return false;

        $apis_id = [];
        foreach($menuApi as $item) $apis_id[] = $item->api_id;
       
        $data = SysApi::where('id', 'in', $apis_id)->select();

        if($data->isEmpty()) return false;

        $rules = [];
        $roule_name = casbin_role_field_prefix($id);

        foreach($data as $api) {
            $act = $api->action == 'ALL' ? "GET|POST|PUT|DELETE":$api->action;
            $rules[]= [$roule_name, $api->path, $act];
            // Permission::addPolicy($rules);
        }
// print_r($rules);
        Permission::addPolicies($rules);
    }

    public static function getOptions(){
        $data = self::where("status", 1)->select();

        if($data->isEmpty()) return [];

        $res = [];
        foreach($data->toArray() as $item){
            $res[$item['id']] = empty($item['label']) ? $item['name']:$item['label'];
        }

        return $res;
    }
}